/***************************************************************************
 *   Copyright (C) 2008 by Philipp Müller                                  *
 *   philipp.mueller@gmx.de                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA          *
 ***************************************************************************/

#include <QtDebug>
#include <QCoreApplication>
#include <QPainter>

#include "channellistmodel.h"

ChannelListModel::ChannelListModel( QObject *parent ) : QAbstractListModel( parent )
{
}


int ChannelListModel::rowCount( const QModelIndex &/*parent*/ ) const
{
    return m_channelList.count();
}


QVariant ChannelListModel::data( const QModelIndex &index, int role ) const
{
    if ( !index.isValid() )
        return QVariant();

    if ( index.row() >= m_channelList.size() )
        return QVariant();

    switch ( role )
    {

        case ChannelListModel::ChannelNameRole:
            return m_channelList.at( index.row() ).name;

        case ChannelListModel::ChannelNumberRole:
            return m_channelList.at( index.row() ).channel;

        case ChannelListModel::ChannelTypeRole:
            return m_channelList.at( index.row() ).type;

        case ChannelListModel::ChannelEpgTitleRole:
        {
            updateEpgStatus( index.row() );

            if ( m_channelList.at( index.row() ).channelSchedule.size() > 0 )
            {
                return m_channelList.at( index.row() ).channelSchedule[ 0 ].title;
            }
            else
                return QVariant();
        }

        case ChannelListModel::ChannelEpgSubTitleRole:
        {
            if ( m_channelList.at( index.row() ).channelSchedule.size() > 0 )
                return m_channelList.at( index.row() ).channelSchedule[ 0 ].subTitle;
            else
                return QVariant();
        }

        case ChannelListModel::ChannelEpgDescriptionRole:
        {
            if ( m_channelList.at( index.row() ).channelSchedule.size() > 0 )
                return m_channelList.at( index.row() ).channelSchedule[ 0 ].description;
            else
                return QVariant();
        }

        case ChannelListModel::ChannelEpgTimeRole:
        {
            if ( m_channelList.at( index.row() ).channelSchedule.size() > 0 )
                return m_channelList.at( index.row() ).channelSchedule[ 0 ].time;
            else
                return QVariant();
        }

        case ChannelListModel::ChannelEpgDurationRole:
        {
            if ( m_channelList.at( index.row() ).channelSchedule.size() > 0 )
                return m_channelList.at( index.row() ).channelSchedule[ 0 ].duration;
            else
                return QVariant();
        }

        case ChannelListModel::ChannelIconRole:
            return QCoreApplication::applicationDirPath() +
                   "/images/logos/" +
                   m_channelList.at( index.row() ).name + ".png";

        case ChannelListModel::ChannelEpgNextTitleRole:
        {
            updateEpgStatus( index.row() );

            if ( m_channelList.at( index.row() ).channelSchedule.size() > 1 )
            {
                return m_channelList.at( index.row() ).channelSchedule[ 1 ].title;
            }
            else
                return QVariant();
        }

        case ChannelListModel::ChannelEpgNextTimeRole:
        {
            if ( m_channelList.at( index.row() ).channelSchedule.size() > 1 )
                return m_channelList.at( index.row() ).channelSchedule[ 1 ].time;
            else
                return QVariant();
        }

        case ChannelListModel::ChannelEpgNextDurationRole:
        {
            if ( m_channelList.at( index.row() ).channelSchedule.size() > 1 )
                return m_channelList.at( index.row() ).channelSchedule[ 1 ].duration;
            else
                return QVariant();
        }


        default:
            return QVariant();
    }
}


QVariant ChannelListModel::headerData( int section, Qt::Orientation orientation,
                                       int role ) const
{
    if ( role != Qt::DisplayRole )
        return QVariant();

    if ( orientation == Qt::Horizontal )
        return QString( "Column %1" ).arg( section );
    else
        return QString( "Row %1" ).arg( section );
}


bool ChannelListModel::insertRows( int position, int rows, const QModelIndex &/*parent*/ )
{
    beginInsertRows( QModelIndex(), position, position + rows - 1 );

    for ( int row = 0; row < rows; ++row )
    {
        channelEntry entry;
        m_channelList.insert( position, entry );
    }

    endInsertRows();

    return true;
}


bool ChannelListModel::removeRows( int position, int rows, const QModelIndex &/*parent*/ )
{
    beginRemoveRows( QModelIndex(), position, position + rows - 1 );

    for ( int row = 0; row < rows; ++row )
    {
        m_channelList.removeAt( position );
    }

    endRemoveRows();

    return true;
}


void ChannelListModel::setChannelName( const QString & channelName, int row )
{
    if ( row > m_channelList.count() - 1 || row < 0 )
    {
        qWarning() << "ChannelListModel::setChannelName: row is out of range";
        return;
    }

    m_channelList[row].name = channelName;
}


void ChannelListModel::setChannelNumber( quint32 channelNumber, int row )
{
    if ( row > m_channelList.count() - 1 || row < 0 )
    {
        qWarning() << "ChannelListModel::setChannelName: row is out of range";
        return;
    }

    m_channelList[ row ].channel = channelNumber;
}


void ChannelListModel::setChannelData( channelEntry entry, int row )
{
    if ( row > m_channelList.count() - 1 || row < 0 )
    {
        qWarning() << "ChannelListModel::setChannelName: row is out of range";
        return;
    }

    m_channelList[ row ] = entry;
}


void ChannelListModel::setChannelSchedule( channelScheduleEntry entry, int channel )
{
    int row = rowFromChannel( channel );

    if ( row > m_channelList.count() - 1 || row < 0 )
    {
        qWarning() << "ChannelListModel::setChannelSchedule: row is out of range: row=" << row;
        return;
    }

    m_channelList[ row ].channelSchedule.append( entry );
}


quint32 ChannelListModel::channelFromRow( int row )
{
    return m_channelList[ row ].channel;
}


int ChannelListModel::rowFromChannel( quint32 channel )
{
    for ( int i = 0; i < m_channelList.size(); ++i )
    {
        if ( m_channelList[ i ].channel == channel )
        {
            return i;
        }
    }

    return -1;
}


void ChannelListModel::updateEpgStatus( int row ) const
{
    bool updateEpg = false;
    quint32 duration = 180 * 60; // min next 180 mins

    if ( m_channelList[ row ].channelScheduleLastUpdate < QDateTime::currentDateTime() )
    {
        updateEpg = true;
    }

    if ( m_channelList[ row ].channelSchedule.size() > 0 )
    {
        if ( m_channelList[ row ].channelSchedule[ 0 ].duration > 0 )
        {
            duration = ( m_channelList[ row ].channelSchedule[ 0 ].duration + 1 ) * 60;

            //TODO Change currentDateTime to ServerDateTime
            if ( m_channelList[ row ].channelSchedule[ 0 ].time.addSecs( duration ) < QDateTime::currentDateTime() )
            {
                updateEpg = true;
            }
        }
    }

    if ( updateEpg )
    {
//         qDebug() << "ChannelListModel::updateEpgStatus with row = " << row;

        ChannelListModel* that = const_cast<ChannelListModel*>( this );

        that->m_channelList[ row ].channelScheduleLastUpdate = QDateTime::currentDateTime().addSecs( 300 );

        emit that->getChannelSchedule( m_channelList[ row ].channel, QDateTime::currentDateTime(), duration );
    }
}


void ChannelListModel::updateChannelSchedule( quint32 channel, const QList<channelScheduleEntry> & channelSchedules )
{
//     qDebug() << "ChannelListModel:updateChannelSchedule: size = " << channelSchedules.size() << " and channel" << channel;

    int row = rowFromChannel( channel );
    m_channelList[ row ].channelSchedule.clear();

    for ( int i = 0; i < channelSchedules.size(); ++i )
    {
        setChannelSchedule( channelSchedules[ i ], channel );
    }

    emit dataChanged( index( row ), index( row ) );
}


